package com.ushine.web.template.transactional.controller;

import com.ushine.web.component.exception.ServiceException;
import com.ushine.web.component.http.HttpResponseVO;
import com.ushine.web.template.transactional.service.IFirstTransactionService;
import com.ushine.web.template.transactional.service.ISecondTransactionService;
import com.ushine.web.template.transactional.model.FirstTransactionDO;
import com.ushine.web.template.transactional.model.SecondTransactionDO;
import com.ushine.web.template.transactional.facade.ISecondTransactionFacade;
import com.ushine.web.template.transactional.facade.ITransactionFacade;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Author: yls
 * @Date 2022/2/14 11:40
 * @Description: 事务控制controller
 * @Version 1.0
 **/
@Api(tags = "组件模块-事务控制测试")
@RestController
@RequestMapping("component/transaction")
public class TransactionController {

    @Resource
    private ITransactionFacade transactionFacade;

    @Resource
    private IFirstTransactionService firstTransactionService;

    @Resource
    private ISecondTransactionService secondTransactionService;

    @Resource
    private ISecondTransactionFacade secondTransactionFacade;

    @ApiOperation(value = "正常事务")
    @GetMapping("insertNormal")
    public HttpResponseVO<Object> insertTransaction() {
        FirstTransactionDO firstTransaction = new FirstTransactionDO();
        firstTransaction.setUsername("first_normal_01");
        SecondTransactionDO secondTransaction = new SecondTransactionDO();
        secondTransaction.setUsername("second_normal_01");
        transactionFacade.insetFirstAndSecond(firstTransaction, secondTransaction);
        return new HttpResponseVO<String>().ok("");
    }

    @ApiOperation(value = "事务回滚")
    @GetMapping("insertException")
    public HttpResponseVO<Object> insertTransactionException() throws ServiceException {
        // 模拟事务回滚
        FirstTransactionDO firstTransaction = new FirstTransactionDO();
        firstTransaction.setUsername("first_exception_003");
        SecondTransactionDO secondTransaction = new SecondTransactionDO();
        secondTransaction.setUsername("second_exception_003");
        transactionFacade.insetFirstAndSecondException(firstTransaction, secondTransaction);
        return new HttpResponseVO<String>().ok("");
    }


    @ApiOperation(value = "事务回滚(nested)")
    @GetMapping("insertNestedException")
    public HttpResponseVO<Object> insertNestedException() throws ServiceException {
        // 模拟事务回滚
        FirstTransactionDO firstTransaction = new FirstTransactionDO();
        firstTransaction.setUsername("first_exception_03");
        SecondTransactionDO secondTransaction = new SecondTransactionDO();
        secondTransaction.setUsername("second_exception_03");
        transactionFacade.insetNestedException(firstTransaction, secondTransaction);
        return new HttpResponseVO<String>().ok("");
    }

    @ApiOperation(value = "嵌套正常事务")
    @GetMapping("insertNestingNormal")
    public HttpResponseVO<Object> insertNestingTransaction() {
        FirstTransactionDO firstTransaction = new FirstTransactionDO();
        firstTransaction.setUsername("first_normal_02");
        SecondTransactionDO secondTransaction = new SecondTransactionDO();
        secondTransaction.setUsername("second_normal_02");
        FirstTransactionDO firstTransaction02 = new FirstTransactionDO();
        firstTransaction02.setUsername("first_normal_03");
        SecondTransactionDO secondTransaction02 = new SecondTransactionDO();
        secondTransaction02.setUsername("second_normal_03");
        secondTransactionFacade.insetFirstAndSecond(firstTransaction, firstTransaction02,
                secondTransaction, secondTransaction02);
        return new HttpResponseVO<String>().ok("");
    }

    @ApiOperation(value = "嵌套事务回滚")
    @GetMapping("insertNestingException")
    public HttpResponseVO<Object> insertNestingTransactionException() throws ServiceException {
        // 模拟事务回滚
        FirstTransactionDO firstTransaction = new FirstTransactionDO();
        firstTransaction.setUsername("first_exception_01");
        SecondTransactionDO secondTransaction = new SecondTransactionDO();
        secondTransaction.setUsername("second_exception_01");
        FirstTransactionDO firstTransaction02 = new FirstTransactionDO();
        firstTransaction02.setUsername("first_exception_02");
        SecondTransactionDO secondTransaction02 = new SecondTransactionDO();
        secondTransaction02.setUsername("second_exception_02");
        secondTransactionFacade.insetFirstAndSecondException(firstTransaction, firstTransaction02,
                secondTransaction, secondTransaction02);
        return new HttpResponseVO<String>().ok("");
    }


    @ApiOperation(value = "事务回滚(嵌套事务-nested)")
    @GetMapping("insertNestedExceptions")
    public HttpResponseVO<Object> insertNestedExceptions() throws ServiceException {
        // 模拟事务回滚
        FirstTransactionDO firstTransaction = new FirstTransactionDO();
        firstTransaction.setUsername("first_exception_02");
        SecondTransactionDO secondTransaction = new SecondTransactionDO();
        secondTransaction.setUsername("second_exception_02");
        FirstTransactionDO firstTransaction02 = new FirstTransactionDO();
        firstTransaction02.setUsername("first_exception_03");
        SecondTransactionDO secondTransaction02 = new SecondTransactionDO();
        secondTransaction02.setUsername("second_exception_03");
        secondTransactionFacade.insetNestedException(firstTransaction, firstTransaction02,
                secondTransaction, secondTransaction02);
        return new HttpResponseVO<String>().ok("");
    }

    @ApiOperation(value = "first事务数据查询")
    @GetMapping("listFirsts")
    public HttpResponseVO<List<FirstTransactionDO>> listFirstTransactions() {
        List<FirstTransactionDO> firstTransactions = firstTransactionService.listFirstTransactions();
        return new HttpResponseVO<List<FirstTransactionDO>>().ok("", firstTransactions);
    }

    @ApiOperation(value = "second事务数据查询")
    @GetMapping("listSeconds")
    public HttpResponseVO<List<SecondTransactionDO>> listSecondTransactions() {
        List<SecondTransactionDO> secondTransactions = secondTransactionService.listSecondTransactions();
        return new HttpResponseVO<List<SecondTransactionDO>>().ok("", secondTransactions);
    }

}
